class TPZSyncEventTarget {
    constructor() {
        this.listeners = {};
    }

    addEventListener(event, listener) {
        if (!this.listeners[event]) {
            this.listeners[event] = [];
        }
        this.listeners[event].push(listener);
    }

    async dispatchEvent(event) {
        const listeners = this.listeners[event.type] || [];
        for (const listener of listeners) {
            if (event.cancelable && event.defaultPrevented) {
                break;
            }
            if (listener.constructor.name === 'AsyncFunction') {
                await listener(event);
            } else {
                listener(event);
            }
        }
    }
}

const eventBus = new TPZSyncEventTarget();

// 注意：事件名称的命名规则需要参考此处：
const EVENT_AFTER_BUILD_HOUSE = "AFTER_BUILD_HOUSE"; // 建造房子结束
const EVENT_BEFORE_HOUSE_RENOVATION = "BEFORE_HOUSE_RENOVATION"; // 房屋翻新前
const EVENT_AFTER_HOUSE_RENOVATION = "AFTER_HOUSE_RENOVATION"; // 房屋翻新后
const EVENT_CURRENT_ROUND_END = "CURRENT_ROUND_END"; // 当前轮次结束
const EVENT_START_NEW_ROUND = "START_NEW_ROUND"; // 开始新的一个轮次
const EVENT_FENCE_BUILDING_COMPLETED = "FENCE_BUILDING_COMPLETED"; // 建栅栏完成，并且至少使用了1个栅栏
const EVENT_RESOURCE_GROWTH = "resourceGrowth"; // 资源增长
const EVENT_USE_RESOURCE_ACCUMULATION = "USE_RESOURCE_ACCUMULATION"; // 使用资源累积格
const EVENT_USE_RESOURCE = "USE_RESOURCE"; // 使用非积累的资源格 （例如 临时工 等）
const EVENT_AFTER_ADD_FAMILY_MEMBER = "AFTER_ADD_FAMILY_MEMBER"; // 增加家庭成员之后
const EVENT_AFTER_GO_HOME = "AFTER_GO_HOME"; // 回家之后
const EVENT_HARVEST_FOR_CELL = "HARVEST_FOR_CELL"; // 针对指定cell农田的收获（在收获阶段）
const EVENT_HARVEST_AFTER_REAP = "HARVEST_AFTER_REAP"; // 所有农田收获之后
const EVENT_PLOW_FIELD = "PLOW_FIELD"; // 使用”犁田“行动格
const EVENT_GRAIN_UTILIZATION = "GRAIN_UTILIZATION"; // 使用”运用谷物“行动格
const EVENT_FARMING = "FARMING"; // 使用”耕种“行动格
const EVENT_USE_OCCUPATION_TRAINING = "USE_OCCUPATION_TRAINING"; // 使用“职业训练”行动格
const EVENT_USE_TURN_ACTION_BEFORE = "USE_TURN_ACTION_BEFORE"; // 使用轮次行动格前


// 返回值为 true 表示事件分发成功结束
// 注意：项目中抛出事件优先使用这个封装方法，而不直接使用eventBus
async function dispatchEvent(eventName, detail = {}, cancelable = false) {
    const event = new CustomEvent(eventName, {
        detail: detail,
        cancelable: cancelable,
    });
    await eventBus.dispatchEvent(event);

    // 如果事件被取消，则返回false，否则返回true
    return !event.defaultPrevented;
}

// 带有延迟功能的事件分发方法，先延迟再分发。这类事件无法被取消。主要用于需要UI先刷新再响应事件的场景。
function dispatchEventDelay(eventName, detail = {}, delay = 1) {
    setTimeout(async ()=> {
        await dispatchEvent(eventName, detail);
    }, delay);
}